package co.edu.javeriana.monopoly.server.eventos;

import co.edu.javeriana.monopoly.server.modelo.ArcaComunal;
import co.edu.javeriana.monopoly.server.modelo.Cartas;
import co.edu.javeriana.monopoly.server.modelo.Casilla;
import co.edu.javeriana.monopoly.server.modelo.Casualidad;
import co.edu.javeriana.monopoly.server.modelo.Dado;
import co.edu.javeriana.monopoly.server.modelo.EstadoJugador;
import co.edu.javeriana.monopoly.server.modelo.Evento;
import co.edu.javeriana.monopoly.server.modelo.IrCarcel;
import co.edu.javeriana.monopoly.server.modelo.Jugada;
import co.edu.javeriana.monopoly.server.modelo.Jugador;
import co.edu.javeriana.monopoly.server.modelo.Monopoly;

import co.edu.javeriana.monopoly.server.modelo.MonopolyException;

import co.edu.javeriana.monopoly.server.modelo.ParadaLibre;
import co.edu.javeriana.monopoly.server.modelo.Propiedad;
import co.edu.javeriana.monopoly.server.modelo.Salida;
import co.edu.javeriana.monopoly.server.modelo.Terreno;

import co.edu.javeriana.monopoly.server.modelo.Vertice;

import java.rmi.RemoteException;

public class LanzarDados extends Evento {
    public LanzarDados(Object[] _objects) {
        super(_objects);
    }

    public void ejecutar() throws MonopolyException {
        Monopoly m;
        try {
            m = Monopoly.getMonopoly();
        } catch (RemoteException e) {
            throw new MonopolyException("Error al trae el juego",e);
        }
        Jugador jugador = (Jugador) m.getTablero().getJugadores().get(getJugada().getJugador().getId());
        Evento e = null;
        Jugada nextjugada = new Jugada();
        
        Dado d = Dado.lanzar();
        jugador.setDado(d);
        
        if ( jugador.getEstado() == EstadoJugador.EnTurno && !jugador.isEstaCarcel() ){
            int suma =  d.getResultado1() + d.getResultado2();
            int posactual = 0;
            if ( jugador.getCasilla() != null ){
                posactual  = jugador.getCasilla().getPosicion();   
            }
            int newpos = posactual + suma;
            if (newpos > m.getTablero().POSICIONES ) {
                newpos = newpos - m.getTablero().POSICIONES;
                Jugada intermediariajugada = new Jugada();
                intermediariajugada.setJugador(jugador);
                intermediariajugada.setMonopoly(m);
                Evento eintermediaria = new PagarSalida(new Object[]{new Integer(m.getTablero().getPagosalida())});
                intermediariajugada.setRegla(eintermediaria);
                try {
                    m.enviarNotificacion(intermediariajugada);
                } catch (RemoteException f) {
                     throw new MonopolyException("Error al notificar la salida",f);
                }
            }
            Casilla casillanueva = (Casilla)m.getTablero().getCasillas().get(new Integer(newpos));
            if (jugador.getCasilla() != null ){
                Casilla casillaactual = (Casilla)m.getTablero().getCasillas().get(new Integer(jugador.getCasilla().getPosicion()));
                casillaactual.quitarJugador(jugador);
            }
            casillanueva.getJugadores().add(jugador);
            jugador.setCasilla(casillanueva);
            if ( casillanueva instanceof Propiedad ){
                if ( ((Propiedad)casillanueva).getPropietario() != null ) {
                    
                    nextjugada.setJugador(jugador);
                    nextjugada.setMonopoly(m);
                    e = new CobrarRenta(new Object[]{new Integer(((Propiedad)casillanueva).valorTotalAlquiler())});
                    e.ejecutar();
                    return;
                }
                else {
                    nextjugada.setJugador(jugador);
                    nextjugada.setMonopoly(m);
                    e = new Comprar(new Object[]{casillanueva});
                    nextjugada.setRegla(e);
                }
            }else 
            if (casillanueva instanceof Cartas){
                Cartas carta = null;
                if (casillanueva instanceof Casualidad){
                    carta = m.getTablero().traerCasualidad();
                }else{
                    carta = m.getTablero().traerArcaComunal();    
                }
                nextjugada.setJugador(jugador);
                nextjugada.setMonopoly(m);
                e = (Evento)carta.getRegla();
                nextjugada.setRegla(e);
            }else if (casillanueva instanceof Vertice){
                if (casillanueva instanceof Salida){
                    nextjugada = new Jugada();
                    nextjugada.setJugador(jugador);
                    nextjugada.setMonopoly(m);
                    e = new PagarSalida(new Object[]{new Integer(m.getTablero().getPagosalida())});
                    nextjugada.setRegla(e);
                }else if (casillanueva instanceof IrCarcel){
                    jugador.setEstaCarcel(true);
                    Casilla casillacarcel = (Casilla)m.getTablero().getCasillas().get(11);
                    casillanueva.quitarJugador(jugador);
                    casillacarcel.getJugadores().add(jugador);
                    jugador.setCasilla(casillacarcel);
                    nextjugada = new Jugada();
                    nextjugada.setJugador(jugador);
                    nextjugada.setMonopoly(m);
                    if (jugador.getDado().sonPares()){
                        e = new ResultadoPares(null);
                    }else{
                        e = new FinTurno(null);
                    }
                    nextjugada.setRegla(e);
                }else {
                    nextjugada = new Jugada();
                    nextjugada.setJugador(jugador);
                    nextjugada.setMonopoly(m);
                    if (jugador.getDado().sonPares()){
                        e = new ResultadoPares(null);
                    }else{
                        e = new FinTurno(null);
                    }
                    nextjugada.setRegla(e);
                }
            }
            
            
        }else if ( jugador.getEstado() == EstadoJugador.EnTurno && jugador.isEstaCarcel() ){
            int intentos = jugador.getIntentosSalidaCarcel();
            intentos++;
            if (intentos == jugador.MAXINTENTOSALIDA){
                intentos = 0;
                jugador.setEstaCarcel(false);
            }
            
            nextjugada = new Jugada();
            nextjugada.setJugador(jugador);
            nextjugada.setMonopoly(m);
            if (jugador.getDado().sonPares()){
                e = new ResultadoPares(null);
            }else{
                e = new FinTurno(null);
            }
            nextjugada.setRegla(e);
            
        }else{
            throw new MonopolyException("No se encuentra en turno, espere su turno",new Exception());
        }
        
        try {
            m.enviarNotificacion(nextjugada);
        } catch (RemoteException f) {
             throw new MonopolyException("Error al notificar el proximo evento",f);
        }
    }
    
    
}
